package com.ming.service.strategy.impl;

import com.ming.config.properties.FileUploadProperties;
import com.ming.pojo.vo.FileUploadVO;
import com.ming.service.strategy.FileUploadStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

/**
 * 本地文件上传策略实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class LocalFileUploadStrategy implements FileUploadStrategy {

    private final FileUploadProperties fileUploadProperties;

    @Override
    public FileUploadVO uploadFile(MultipartFile file, String originalFileName, String contentType, long fileSize) throws IOException {
        // 1. 生成唯一文件名
        String fileExtension = getFileExtension(originalFileName);
        String uniqueFileName = generateUniqueFileName(fileExtension);

        // 2. 创建上传目录（如果不存在）
        String datePath = getDatePath();
        String uploadPath = fileUploadProperties.getLocal().getUploadPath();
        String accessUrl = fileUploadProperties.getLocal().getAccessUrl();
        Path targetPath = Paths.get(uploadPath, datePath, uniqueFileName);

        createUploadDirectory(uploadPath, datePath);

        // 3. 保存文件到本地
        Files.copy(file.getInputStream(), targetPath);

        // 4. 构建返回结果
        String relativePath = datePath + "/" + uniqueFileName;
        String fileUrl = accessUrl + "/" + relativePath;

        FileUploadVO uploadVO = new FileUploadVO();
        uploadVO.setFileName(uniqueFileName);
        uploadVO.setOriginalFileName(originalFileName);
        uploadVO.setFileSize(fileSize);
        uploadVO.setContentType(contentType);
        uploadVO.setFileUrl(fileUrl);
        uploadVO.setUploadTime(LocalDateTime.now());
        uploadVO.setStoragePath(targetPath.toString());

        log.info("本地文件上传成功: {} -> {}", originalFileName, targetPath);
        return uploadVO;
    }

    @Override
    public void deleteFile(String fileName) throws IOException {
        String uploadPath = fileUploadProperties.getLocal().getUploadPath();
        Path filePath = Paths.get(uploadPath, fileName);
        if (Files.exists(filePath)) {
            Files.delete(filePath);
            log.info("本地文件删除成功: {}", filePath);
        } else {
            throw new IOException("文件不存在: " + fileName);
        }
    }

    @Override
    public String getStorageType() {
        return "local";
    }

    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String filename) {
        if (filename == null || filename.isEmpty()) {
            return "";
        }
        int lastDotIndex = filename.lastIndexOf('.');
        return lastDotIndex > 0 ? filename.substring(lastDotIndex) : "";
    }

    /**
     * 生成唯一文件名
     */
    private String generateUniqueFileName(String fileExtension) {
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String uuid = UUID.randomUUID().toString().replace("-", "");
        return timestamp + "_" + uuid + fileExtension;
    }

    /**
     * 创建上传目录
     */
    private void createUploadDirectory(String uploadPath, String datePath) throws IOException {
        Path directory = Paths.get(uploadPath, datePath);
        if (!Files.exists(directory)) {
            Files.createDirectories(directory);
            log.info("创建上传目录: {}", directory);
        }
    }

    /**
     * 获取日期路径（用于按日期分类存储）
     */
    private String getDatePath() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
    }
}